<!DOCTYPE html>
<title>ObjectContainer Tests</title>
<script src="../src/ObjectContainer.js"></script>
<script>
    
    function assert(expr, message) {        
        if (!expr) {
            document.write('<span style="color: red">' + message + '</span><br/>');
            throw new Error(message);
        }
    }
    
    function ExampleObject(name) {
        this.name = name;
    }
    
    ExampleObject.prototype.dump = function (a) {
        document.writeln('<i>Called ExampleObject("' + this.name + '").dump("' + a + '")</i><br/>');        
        return a;
    };
        
    var oc = new ObjectContainer();

    var first = new ExampleObject("first"),
        second = new ExampleObject("second"),
        third = new ExampleObject("third"),
        named_object = new ExampleObject("named");

    oc.add(first);
    oc.add(second);
    oc.add(third);

    assert(oc.objects[0] === first, "ObjectContainer.add(object) test failed!");
    assert(oc.objects[1] === second, "ObjectContainer.add(object) test failed!");
    assert(oc.objects[2] === third, "ObjectContainer.add(object) test failed!");

    document.write("ObjectContainer.add(object) test passed.<br/><br/>");

    oc.remove(first);
    assert(oc.objects[0] === null, "ObjectContainer.remove(object) test failed!");
    document.write("ObjectContainer.remove(object) test passed.<br/><br/>");

    oc.remove(2);
    assert(oc.objects[2] === null, "ObjectContainer.remove(id) test failed!");        
    document.write("ObjectContainer.remove(id) test passed.<br/><br/>");

    oc.add(named_object, "name");
    assert(oc.objects[3] === named_object, "ObjectContainer.add(object, name) test failed!");
    assert(oc.names["name"] === 3, "ObjectContainer.add(object, name) test failed!");
    document.write("ObjectContainer.add(object, name) test passed.<br/><br/>");
    
    assert(oc.nameOf(named_object), "name", "ObjectContainer.nameOf() test failed!");
    assert(oc.nameOf(3), "name", "ObjectContainer.nameOf() test failed!");
    document.write("ObjectContainer.nameOf() test passed.<br/><br/>");
    
    assert(oc.indexOf(named_object) === 3, "ObjectContainer.indexOf() test failed!");
    assert(oc.indexOf("name") === 3, "ObjectContainer.indexOf() test failed!");
    document.write("ObjectContainer.indexOf() test passed.<br/><br/>");
    
    oc.remove("name");    
    assert(oc.objects[3] === null, "ObjectContainer.remove(name) test failed! The object is still present.");
    assert(!("name" in oc.names), "ObjectContainer.remove(name) test failed! The object name is still present.");
    document.write("ObjectContainer.remove(name) test passed.<br/><br/>"); 
    
    oc = new ObjectContainer();
    oc.add(first);
    oc.insert(first, second, 'Second', true);
    assert(oc.objects[1] === second, "ObjectContainer.insert(after) test failed!");
    document.write("ObjectContainer.insert(after) test passed.<br/><br/>"); 
    oc.remove(second);
    oc.insert(first, second);
    assert(oc.objects[0] === second, "ObjectContainer.insert(before) test failed!");
    document.write("ObjectContainer.insert(before) test passed.<br/><br/>"); 
    
    oc = new ObjectContainer();        
    function closure(s) { 
        return function (a) {        
            document.writeln("<i>Called function " + s + " with argument: " + a + "</i><br/>");
            return s;
        };        
    }
    oc.add(closure(0));
    oc.add(closure(1));
    oc.add(closure(2));
    results = oc.call("test");
    assert(results[0] === 0, "ObjectContainer.call(...) test failed!");
    assert(results[1] === 1, "ObjectContainer.call(...) test failed!");
    assert(results[2] === 2, "ObjectContainer.call(...) test failed!");
    document.write("ObjectContainer.call(...) test passed.<br/><br/>");
    
    oc = new ObjectContainer();
    oc.add(first, "first");
    oc.add(second);
    oc.add(third);    
    var results = oc.invoke("dump", "test");        
    assert(results[0] === "test", "ObjectContainer.invoke(...) test failed!");
    assert(results[1] === "test", "ObjectContainer.invoke(...) test failed!");
    assert(results[2] === "test", "ObjectContainer.invoke(...) test failed!");
    document.write("ObjectContainer.invoke(...) test passed.<br/><br/>");
    
    function proc(object) {
        object.x = "test";
        return true;
    }
    oc.each(proc);
    assert(oc.objects[0].x === "test", "ObjectContainer.invoke(...) test failed!");
    assert(oc.objects[1].x === "test", "ObjectContainer.invoke(...) test failed!");
    assert(oc.objects[2].x === "test", "ObjectContainer.invoke(...) test failed!");
    document.write("ObjectContainer.each(...) test passed.<br/><br/>");    
    
    assert(oc.get(1) === second, "ObjectContainer.get(id) test failed!");
    assert(oc.get("first") === first, "ObjectContainer.get(name) test failed!");
    document.write("ObjectContainer.get(...) tests passed.<br/><br/>");            
</script>